home *** CD-ROM | disk | FTP | other *** search
/ TPUG - Toronto PET Users Group / TPUG Users Group CD / TPUG Users Group CD.iso / AMIGA / AMICUS / AMICUS05.ADF / IFF / ilbmr.c < prev    next >
C/C++ Source or Header  |  1986-04-20  |  6KB  |  149 lines

  1.  
  2. /*----------------------------------------------------------------------*
  3.  * ILBMR.C  Support routines for reading ILBM files.           11/27/85
  4.  * (IFF is Interchange Format File.)
  5.  *
  6.  * By Jerry Morrison and Steve Shaw, Electronic Arts.
  7.  * This software is in the public domain.
  8.  *
  9.  * This version for the Commodore-Amiga computer.
  10.  *----------------------------------------------------------------------*/
  11. #include "iff/packer.h"
  12. #include "iff/ilbm.h"
  13.  
  14.  
  15. /* ---------- GetCMAP ------------------------------------------------*/
  16. /* pNColorRegs is passed in as a pointer to the number of ColorRegisters
  17.  * caller has space to hold.  GetCMAP sets to the number actually read.*/
  18. IFFP GetCMAP(ilbmContext, colorMap, pNColorRegs)   
  19.       GroupContext *ilbmContext;  WORD *colorMap;  UBYTE *pNColorRegs;
  20.    {
  21.    register int nColorRegs;   
  22.    register IFFP iffp;
  23.    ColorRegister colorReg;
  24.  
  25.    nColorRegs = ilbmContext->ckHdr.ckSize / sizeofColorRegister;
  26.    if (*pNColorRegs < nColorRegs)   nColorRegs = *pNColorRegs;
  27.    *pNColorRegs = nColorRegs; /* Set to the number actually there.*/
  28.  
  29.    for ( ;  nColorRegs > 0;  --nColorRegs)  {
  30.       iffp = IFFReadBytes(ilbmContext, (BYTE *)&colorReg,sizeofColorRegister);
  31.       CheckIFFP();
  32.       *colorMap++ = ( ( colorReg.red   >> 4 ) << 8 ) |
  33.               ( ( colorReg.green >> 4 ) << 4 ) |
  34.               ( ( colorReg.blue  >> 4 )      );
  35.       }
  36.    return(IFF_OKAY);
  37.    }
  38.  
  39. /*---------- GetBODY ---------------------------------------------------*/
  40. /* NOTE: This implementation could be a LOT faster if it used more of the
  41.  * supplied buffer. It would make far fewer calls to IFFReadBytes (and
  42.  * therefore to DOS Read) and to movemem. */
  43. IFFP GetBODY(context, bitmap, mask, bmHdr, buffer, bufsize)
  44.       GroupContext *context;  struct BitMap *bitmap;  BYTE *mask;
  45.       BitMapHeader *bmHdr;  BYTE *buffer;  LONG bufsize;
  46.    {
  47.    register IFFP iffp;
  48.    UBYTE srcPlaneCnt = bmHdr->nPlanes;   /* Haven't counted for mask plane yet*/
  49.    WORD srcRowBytes = RowBytes(bmHdr->w);
  50.    LONG bufRowBytes = MaxPackedSize(srcRowBytes);
  51.    int nRows = bmHdr->h;
  52.    Compression compression = bmHdr->compression;
  53.    register int iPlane, iRow, nEmpty;
  54.    register WORD nFilled;
  55.    BYTE *buf, *nullDest, *nullBuf, **pDest;
  56.    BYTE *planes[MaxSrcPlanes]; /* array of ptrs to planes & mask */
  57.  
  58.    if (compression > cmpByteRun1)
  59.       return(CLIENT_ERROR);
  60.  
  61.    /* Complain if client asked for a conversion GetBODY doesn't handle.*/
  62.    if ( srcRowBytes  !=  bitmap->BytesPerRow  ||
  63.          bufsize < bufRowBytes * 2  ||
  64.          srcPlaneCnt > MaxSrcPlanes )
  65.       return(CLIENT_ERROR);
  66.  
  67.    if (nRows > bitmap->Rows)
  68.       nRows = bitmap->Rows;
  69.    
  70.    /* Initialize array "planes" with bitmap ptrs; NULL in empty slots.*/
  71.    for (iPlane = 0; iPlane < bitmap->Depth; iPlane++)
  72.       planes[iPlane] = (BYTE *)bitmap->Planes[iPlane];
  73.    for ( ;  iPlane < MaxSrcPlanes;  iPlane++)
  74.       planes[iPlane] = NULL;
  75.  
  76.    /* Copy any mask plane ptr into corresponding "planes" slot.*/
  77.    if (bmHdr->masking == mskHasMask) {
  78.       if (mask != NULL)
  79.          planes[srcPlaneCnt] = mask;  /* If there are more srcPlanes than
  80.                * dstPlanes, there will be NULL plane-pointers before this.*/
  81.       else
  82.          planes[srcPlaneCnt] = NULL;  /* In case more dstPlanes than src.*/
  83.       srcPlaneCnt += 1;  /* Include mask plane in count.*/
  84.       }
  85.  
  86.    /* Setup a sink for dummy destination of rows from unwanted planes.*/
  87.    nullDest = buffer;
  88.    buffer  += srcRowBytes;
  89.    bufsize -= srcRowBytes;
  90.  
  91.    /* Read the BODY contents into client's bitmap.
  92.     * De-interleave planes and decompress rows.
  93.     * MODIFIES: Last iteration modifies bufsize.*/
  94.    buf = buffer + bufsize;  /* Buffer is currently empty.*/
  95.    for (iRow = nRows; iRow > 0; iRow--)  {
  96.       for (iPlane = 0; iPlane < srcPlaneCnt; iPlane++)  {
  97.  
  98.          pDest = &planes[iPlane];
  99.  
  100.          /* Establish a sink for any unwanted plane.*/
  101.          if (*pDest == NULL) {
  102.          nullBuf = nullDest;
  103.             pDest   = &nullBuf;
  104.             }
  105.  
  106.          /* Read in at least enough bytes to uncompress next row.*/
  107.          nEmpty  = buf - buffer;     /* size of empty part of buffer.*/
  108.          nFilled = bufsize - nEmpty;      /* this part has data.*/
  109.       if (nFilled < bufRowBytes) {
  110.          /* Need to read more.*/
  111.  
  112.          /* Move the existing data to the front of the buffer.*/
  113.          /* Now covers range buffer[0]..buffer[nFilled-1].*/
  114.             movmem(buf, buffer, nFilled);  /* Could be moving 0 bytes.*/
  115.  
  116.             if (nEmpty > ChunkMoreBytes(context)) {
  117.                /* There aren't enough bytes left to fill the buffer.*/
  118.                nEmpty = ChunkMoreBytes(context);
  119.                bufsize = nFilled + nEmpty;  /* heh-heh */
  120.                }
  121.  
  122.          /* Append new data to the existing data.*/
  123.             iffp = IFFReadBytes(context, &buffer[nFilled], nEmpty);
  124.             CheckIFFP();
  125.  
  126.             buf     = buffer;
  127.          nFilled = bufsize;
  128.          nEmpty  = 0;
  129.          }
  130.  
  131.          /* Copy uncompressed row to destination plane.*/
  132.          if (compression == cmpNone) {
  133.             if (nFilled < srcRowBytes)  return(BAD_FORM);
  134.          movmem(buf, *pDest, srcRowBytes);
  135.          buf    += srcRowBytes;
  136.             *pDest += srcRowBytes;
  137.             }
  138.       else
  139.          /* Decompress row to destination plane.*/
  140.             if ( UnPackRow(&buf, pDest, nFilled,  srcRowBytes) )
  141.                     /*  pSource, pDest, srcBytes, dstBytes  */
  142.                return(BAD_FORM);
  143.          }
  144.       }
  145.  
  146.    return(IFF_OKAY);
  147.    }
  148.  
  149.